package org.jeecg.config.init;

import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.vo.ExtraData;
import org.springframework.core.MethodParameter;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;

import java.util.Iterator;

public class MethodArgumentResolver implements HandlerMethodArgumentResolver {

    private ServletModelAttributeMethodProcessor methodProcessor;
    private static ExpressionParser parser = new SpelExpressionParser();


    public MethodArgumentResolver() {
        methodProcessor = new ServletModelAttributeMethodProcessor(true);
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return ExtraData.class.isAssignableFrom(parameter.getParameterType())
                || parameter.getParameterType() == LoginUser.class;
    }

    @Override
    public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                        NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        Object obj = methodProcessor.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
        // 将以extraParam.开头的参数注入的ExtraParam对象的map属性中
        if(obj !=null && obj instanceof ExtraData){
            handerExtraParam(webRequest,(ExtraData)obj);
        }else if(parameter.getParameterType() == LoginUser.class){
            obj = SecurityUtils.getSubject().getPrincipal();
        }
        return obj;
    }

    private void handerExtraParam(WebRequest webRequest, ExtraData param){
        Iterator<String> names = webRequest.getParameterNames();
        while(names.hasNext()){
            String key = names.next();
            if(key.startsWith(ExtraData.PREFIX)){ //key = extraPara.startDateS
                String value = webRequest.getParameter(key);
                param.put(key.substring(ExtraData.PREFIX.length()), value);//startDateS
            }
        }
    }

}
